<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\LayuiController;
use App\Jobs\ExportData;
use App\Models\AccountLog;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use SuperClosure\Serializer;

class RechargeRecordController extends Controller
{
    /**
     * 列表页视图
     * @name index
     * @param \Illuminate\Contracts\View\Factory|\Illuminate\View\View
     * @author Mr.Liu
     * @return JsonStr
     * @datetime 2019/5/23 10:23
     */
    public function index(){

        /* 查询历史累计充值 */
        $data['historyAll'] = DB::table('account_log')
            ->where('account_type',AccountLog::EIGHT_BALANCE)
            ->whereIn('type',[AccountLog::RECHARGE_TYPE,AccountLog::ADMIN_RECHARGE_TYPE])
            ->sum('money');

        /* 查询昨日充值 */
        $data['yesterdayAll'] = DB::table('account_log')
            ->where('account_type',AccountLog::EIGHT_BALANCE)
            ->whereIn('type',[AccountLog::RECHARGE_TYPE,AccountLog::ADMIN_RECHARGE_TYPE])
            ->whereDate('created_at',Carbon::yesterday()->toDateString())
            ->sum('money');

        /* 查询平台全部用户余额 */
        $data['platformAll'] = DB::table('user_account')
            ->whereExists(function ($query) {
                $query->select(DB::raw(1))
                    ->from('user')
                    ->whereColumn('user_account.user_id','user.id');
            })
            ->sum('money_recharge');

        array_walk_recursive($data, function (&$item) {
            $item = number_format($item,2,".","");
        });

        return view('Admin.rechargeRecord.index', ['data' => $data]);
    }

    /**
     * 列表页表格数据方法
     * @name table
     * @param array
     * @author Mr.Liu
     * @return JsonStr
     * @datetime 2019/5/21 9:43
     */
    public function table(Request $request){

        $payload = $request->all();

        /* 查询部门列表 */
        $departmentList = DB::table('user_department')
            ->get()
            ->mapWithKeys(function($item){
               return [$item->id => $item->department_name];
            });

        $status = array_get($payload,'status');

        $preData = AccountLog::with(['userInfo','userInfo.inviteUserInfo','userInfo.userAccountInfo'])
            ->when($keyword = array_get($payload,'keyword'),function($query)use($keyword){
                $query->where(function($query)use($keyword){
                    $query->whereHas('userInfo',function($query)use($keyword){
                        $query->where('nickname', 'like', "%$keyword%")
                            ->orWhere('realname','like', "%$keyword%")
                            ->orWhere('phone','like', "%$keyword%");
                    })->orWhereHas('userInfo.inviteUserInfo',function($query)use($keyword){
                        $query->where('number', 'like', "%$keyword%")
                            ->orWhere('realname','like', "%$keyword%");
                    });
                });
            })
            ->when($total = array_get($payload,'total'),function($query)use($total,$status){
                $query->whereHas('userInfo.userAccountInfo',function($query)use($total,$status) {
                    $query->when($status == AccountLog::FAIL, function ($query) use ($total) {
                        $query->where('fail_recharge', $total);
                    })->when($status == AccountLog::SUCCESS, function ($query) use ($total) {
                        $query->where('success_recharge', $total);
                    })->when(is_null($status), function ($query) use ($total) {
                        $query->whereRaw('success_recharge + fail_recharge = ?', [$total]);
                    });
                });
            })
            ->when($time = array_get($payload,'time'),function($query)use($time){
                $time = explode(' - ',$time);
                $time[1] = Carbon::parse($time[1])->addDay()->toDateString();
                $query->whereBetween('created_at',$time);
            })
            ->when($status,function($query)use($status){
                $query->where('status',$status);
            })
            ->where('account_type',AccountLog::EIGHT_BALANCE)
            ->whereIn('type',[AccountLog::RECHARGE_TYPE,AccountLog::ADMIN_RECHARGE_TYPE])
            ->whereIn('status',[AccountLog::STATUS_YES,AccountLog::STATUS_NO])
            ->orderBy('id','desc')
            ->paginate($request->get('limit',30));

        $data = $preData->map(function($item)use($departmentList,$status){
            if($status == AccountLog::SUCCESS){

                $total = isset($item->userInfo->userAccountInfo->success_recharge) ? $item->userInfo->userAccountInfo->success_recharge : 0;

            }else if($status == AccountLog::FAIL){

                $total = isset($item->userInfo->userAccountInfo->fail_recharge) ? $item->userInfo->userAccountInfo->fail_recharge : 0;

            }else{

                $success = isset($item->userInfo->userAccountInfo->success_recharge) ? $item->userInfo->userAccountInfo->success_recharge : 0;
                $fail = isset($item->userInfo->userAccountInfo->fail_recharge) ? $item->userInfo->userAccountInfo->fail_recharge : 0;
                $total = $success + $fail;

            }
            return [
                'id'                    => $item->id,
                'realname'              => $item->userInfo->realname ?? '',
                'nickname'              => $item->userInfo->nickname ?? '',
                'number'                => $item->userInfo->number ?? '',
                'phone'                 => $item->userInfo->phone ?? '',
                'avatar'                => $item->userInfo->avatar ?? '',
                'invite_user_realname'  => $item->userInfo->inviteUserInfo->realname ?? '',
                'invite_user_number'    => $item->userInfo->inviteUserInfo->number ?? '',
                'invite_user_department'=> isset($item->userInfo->inviteUserInfo->department) ? ($departmentList[$item->userInfo->inviteUserInfo->department] ?? '') : '',
                'money'                 => numberFormat($item->money),
                'balance'               => numberFormat($item->balance),
                'status'                => AccountLog::ACCOUNT_LOG_STATUS[$item->status],
                'created_at'            => $item->created_at,
                'total'                 => $total
            ];
        });

        return LayuiController::tableJson($data,0,$preData->total());
    }

    /**
     * 导出操作
     * @name export
     * @param \Illuminate\Http\JsonResponse
     * @author Mr.Liu
     * @return JsonStr
     * @datetime 2019/5/29 9:12
     */
    public function export(Request $request){
        /* 1 获取查询条件 */
        $payload = $request->all();

        $filename = $request->input('filename','demo.csv');

        $filename = rtrim($filename,'.csv').'.csv';

        if(Storage::disk('exports')->exists($filename))
            return $this->getResponse('文件已存在，请重新输入',[],302,route('rechargeRecord.index'));

        $status = array_get($payload,'status');
        /* 2 查询准备 */
        $query = function() use($payload,$status){
            return AccountLog::with(['userInfo','userInfo.inviteUserInfo','userInfo.userAccountInfo'])
                ->when($keyword = array_get($payload,'keyword'),function($query)use($keyword){
                    $query->where(function($query)use($keyword){
                        $query->whereHas('userInfo',function($query)use($keyword){
                            $query->where('nickname', 'like', "%$keyword%")
                                ->orWhere('realname','like', "%$keyword%")
                                ->orWhere('phone','like', "%$keyword%");
                        })->orWhereHas('userInfo.inviteUserInfo',function($query)use($keyword){
                            $query->where('number', 'like', "%$keyword%")
                                ->orWhere('realname','like', "%$keyword%");
                        });
                    });
                })
                ->when($total = array_get($payload,'total'),function($query)use($total,$status){
                    $query->whereHas('userInfo.userAccountInfo',function($query)use($total,$status) {
                        $query->when($status == AccountLog::FAIL, function ($query) use ($total) {
                            $query->where('fail_recharge', $total);
                        })->when($status == AccountLog::SUCCESS, function ($query) use ($total) {
                            $query->where('success_recharge', $total);
                        })->when(is_null($status), function ($query) use ($total) {
                            $query->whereRaw('success_recharge + fail_recharge = ?', [$total]);
                        });
                    });
                })
                ->when($time = array_get($payload,'time'),function($query)use($time){
                    $time = explode(' - ',$time);
                    $time[1] = Carbon::parse($time[1])->addDay()->toDateString();
                    $query->whereBetween('created_at',$time);
                })
                ->when($status,function($query)use($status){
                    $query->where('status',$status);
                })
                ->where('account_type',AccountLog::EIGHT_BALANCE)
                ->whereIn('type',[AccountLog::RECHARGE_TYPE,AccountLog::ADMIN_RECHARGE_TYPE])
                ->orderBy('id','desc');
        };

        /* 3 数据回调处理 */
        /* 查询部门列表 */
        $departmentList = DB::table('user_department')
            ->get()
            ->mapWithKeys(function($item){
                return [$item->id => $item->department_name];
            });
        $call = function($item) use ($departmentList,$status){
            if($status == AccountLog::SUCCESS){

                $total = isset($item->userInfo->userAccountInfo->success_recharge) ? $item->userInfo->userAccountInfo->success_recharge : 0;

            }else if($status == AccountLog::FAIL){

                $total = isset($item->userInfo->userAccountInfo->fail_recharge) ? $item->userInfo->userAccountInfo->fail_recharge : 0;

            }else{

                $success = isset($item->userInfo->userAccountInfo->success_recharge) ? $item->userInfo->userAccountInfo->success_recharge : 0;
                $fail = isset($item->userInfo->userAccountInfo->fail_recharge) ? $item->userInfo->userAccountInfo->fail_recharge : 0;
                $total = $success + $fail;

            }
            return [
                'realname'              => $item->userInfo->realname,
                'nickname'              => $item->userInfo->nickname,
                'number'                => $item->userInfo->number,
                'phone'                 => $item->userInfo->phone,
                'invite_user_realname'  => $item->userInfo->inviteUserInfo->realname ?? '',
                'invite_user_number'    => $item->userInfo->inviteUserInfo->number ?? '',
                'invite_user_department'=> isset($item->userInfo->inviteUserInfo->department) ? ($departmentList[$item->userInfo->inviteUserInfo->department] ?? '') : '',
                'money'                 => $item->money,
                'balance'               => $item->balance,
                'status'                => AccountLog::ACCOUNT_LOG_STATUS[$item->status],
                'created_at'            => $item->created_at,
                'total'                 => $total,
            ];
        };

        /* 4 定义文件头 */
        $header = [
            'created_at'            => '充值时间',
            'realname'              => '会员姓名',
            'nickname'              => '会员昵称',
            'phone'                 => '会员手机号码',
            'invite_user_realname'  => '员工姓名',
            'invite_user_number'    => '员工ID',
            'invite_user_department'=> '员工部门',
            'money'                 => '充值金额',
            'balance'               => '充值后余额',
            'status'                => '充值状态',
            'total'                 => '充值次数',
        ];

        /* 5 插入队列 */

        /* 闭包序列化处理 */
        $serializer = new Serializer();

        dispatch(new ExportData($header,$serializer->serialize($query),$serializer->serialize($call),$filename));

        return $this->getResponse('已加入导出队列',[],200,route('rechargeRecord.index'));
    }
}
